; (function (window, document, $, undefined) {

	/***************************************
	 *				# Site #
	 *
	 *	Events >> eventName [data]:
	 *		- siteDeviceSet [device properties]
	 *		- siteDeviceChange [old and current device properties]
	 *		- siteViewSet [device properties]
	 *		- siteViewChange [old and current device properties]
	 *		- siteSpinnerShow []
	 *		- siteSpinnerHide []
	 ***************************************/
    function Site(element, options) {
        this.element = $(element);      
        
        this.touchbehavior= !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
        this.device= null;
        this.view= null;
        
        this.roles = {
        	header: '[data-role=header]',
        	page: '[data-role=page]',
        	content: '[data-role=content]',
        	sidebar: '[data-role=sidebar]',
        	nav: '[data-role=nav]',
        	footer: '[data-role=footer]',
        	bgslide: '[data-role=bgslide]'
        }
        
        this.selectors = {
        	device: '[data-role=device] ul li[device]:visible',
        	view: '[data-role=device] ul li[view]:visible',
        	layers: {
        		overlay: '.overlayLayer',
        		spinner: '.overlaySpinner',
        		modal: '.overlayModal'
        	}
        }

        this.options = $.extend(true, {
        	time: {
        		show_roles: 1000,
        		hide_roles: 1000,
        		spinner_transition: 150
        	},
        	scroll: {
    				touchbehavior: this.touchbehavior
			}
        }, options);
        
        this.deviceRanges= {
	        'smartphone': [0, 767],
	    	'tablet': [768, 1024],
	    	'desktop': [1025, 9999999]
	    }
                
        this.bgSlide= null;
        this.navSlide= null;
        
    	this.element.one('siteDeviceSet', $.proxy(function(e,data){
    		clearInterval(this.init_timer);
    		this.init();    	
    	}, this))        
        
        this.init_timer= setInterval( $.proxy( function(){
        	this.init_device();
        }, this), 150);
    }

    $.extend(Site.prototype, {

    	/*** INIT ***/
    	
        init: function () {
    		this.init_triggers();
    		this.init_spinner();    		
			this.init_bgslider();
			this.show();
			this.init_navslider();
			this.init_scroll();
        },       
        
        init_device: function(){
        	var old_device= this.device,
        		old_view= this.view,
        		old_data= this.get_device(),
        		ww = $(window).width(),
        		wh = $(window).height();

        	//Device
    	    for (device in this.deviceRanges) {
    	        var d = this.deviceRanges[device];
    	        if(ww >= d[0] && ww <= d[1]){
    	        	this.device= device;
    	        	break;
    	        }
    	    }

    	    //View
    	    this.view= ( ww > wh ) ? 'landscape' : 'portrait';
        	
        	var event_data= {
        		old_data: old_data,
        		current_data: this.get_device()
        	}
        	
        	if(this.device != old_device){
        		if(old_device==null){
        			this.element.trigger('siteDeviceSet', this.get_device());
        		}
        		else {
        			this.element.trigger('siteDeviceChange', event_data);
        		}
        	}
        	
        	if(this.view != old_view){
        		if(old_view==null){
        			this.element.trigger('siteViewSet', this.get_device())
        		}
        		else {
        			this.element.trigger('siteViewChange', event_data);
        		}
        	}        
        	
        	return this.get_device();
        },
        
        init_spinner: function(){
        	var opts;
        	
    		switch(this.device){
    			case 'desktop':
    				opts = {
    						lines: 13, 				// The number of lines to draw
    						length: 10, 			// The length of each line
    						width: 5, 				// The line thickness
    						radius: 14, 			// The radius of the inner circle

    					};    
    				break;
    			case 'tablet':
    				var opts = {
    						  lines: 13, // The number of lines to draw
    						  length: 7, // The length of each line
    						  width: 4, // The line thickness
    						  radius: 11, // The radius of the inner circle
    						};
    				break;
    			case 'smartphone':
    				var opts = {
    						  lines: 13, // The number of lines to draw
    						  length: 4, // The length of each line
    						  width: 2, // The line thickness
    						  radius: 6, // The radius of the inner circle
    						};
    				break;    				
    		}        	
        	
			$(this.selectors.layers.spinner).center().spin(opts);
        },
        
        init_bgslider: function(){        	
    		$(this.roles.bgslide).bgSlide(this.get_device());
    		this.bgSlide= $(this.roles.bgslide).data('bgslide'); 
        },
        
        init_navslider: function(){
    		var num;
    		
        	switch(this.device){
	        	case 'desktop':
	        		num= 12;
	        		break;
	        	case 'tablet':
	    			num= 8;
	    			break;
	        	case 'smartphone':
	    			num= 3;
	    			break;
        	}
        	
    		$(this.roles.nav).navSlide({items: num});
    		this.navSlide= $(this.roles.nav).data('navslide'); 
        },        
        
        init_triggers: function(){        	
        	$(window).resize($.proxy(function(e){
        		this.init_device();
        		this.init_spinner();
        		
        		$(this.roles.bgslide).data('bgslide').refresh(this.get_device());
        	}, this));
        	
        	$(window).scroll($.proxy(function(e){
        		$(this.selectors.layers.overlay).center();
        		$(this.selectors.layers.spinner).center();
        	}, this));
        	
        	$('.nav-prev').click($.proxy(function(e){
        		e.preventDefault();
        		this.navSlide.prev_page();
        	}, this));
        	
        	$('.nav-next').click($.proxy(function(e){
        		e.preventDefault();
        		this.navSlide.next_page();        		
        	}, this));        	
        	
        	$(document).bind('contextmenu', function(e){
                //return false;
        	});  
        },
        
        init_scroll: function(){
        	var that= this,
        		scrollables= $('[scroll="wrapper"]');
        	
        	$.each(scrollables, $.proxy(function(index, item){
        		if($(item).data('scroll')){
        			var scroll= $(item).data('scroll');
        			scroll.refresh();
        		}
        		else{
        			var options= $.extend(true, {}, this.options.scroll),
        				data= $(item).niceScroll(options);
    				$(item).data('scroll', data);
        		}
        	}, that));
        },      
        
        refresh_scroll: function(){
        	this.init_scroll();
        },
        
        /*** PUBLIC ***/
        
        get_device: function(){
        	return {
    			device: this.device, 
    			view: this.view,
    			width: $(window).width(),
				height: $(window).height()
			};
        },
        
        spinner: function(show){
        	var that= this;
        	
        	if(typeof show != "boolean")
        		show= true;
        	
        	if(show==false){
        		$(this.selectors.layers.overlay).fadeOut(this.options.time.spinner_transition);
        		$(this.selectors.layers.spinner).fadeOut(this.options.time.spinner_transition, $.proxy(function(){ this.element.trigger('siteSpinnerHide'); },that));
        	}
        	else{
        		$(this.selectors.layers.overlay).fadeIn(this.options.time.spinner_transition);
        		$(this.selectors.layers.spinner).fadeIn(this.options.time.spinner_transition, $.proxy(function(){ this.element.trigger('siteSpinnerShow'); }, that));
        	}
        },
        
        show: function(){
        	this.spinner(false);
        	
        	$.each(this.roles, $.proxy(function(key, selector) {
        		$(selector).fadeIn(this.options.time.show_roles);        	
    		}, this));        
        },
        
        hide: function(){        	
        	$.each(this.roles, $.proxy(function(key, selector) {
        		$(selector).fadeOut(this.options.time.hide_roles);
    		}, this));        	
        }
        
        
        
    });

    $.fn.site = function (options) {
	    if (!$(this).data('site')) {
	        $(this).data('site', new Site(this, options));
	    }
	    return $(this).data('site');
    }
    
    
    /***************************************
	 *				NavSlide
	 *	Events >> eventName [data]:
	 *		- bgSlideImageLoad [slide]
	 *		- bgSlideLoad [slides]
	 ***************************************/    
    function NavSlide(element, options){
    	this.element= element;
    	
    	this.touchbehavior= !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
    	
    	this.options= $.extend(true, {
    		scroll_touch: {
    			touchbehavior: false,
    			autohidemode: false,
    			bouncescroll: false,
    			enablemousewheel: false,
    			sensitiverail: false
    		},
    		scroll_no_touch: {
    			touchbehavior: false,
    			autohidemode: true,
    			bouncescroll: false,
    			enablemousewheel: true,
    			sensitiverail: false
    		},
			items: 6			
    	}, options);
    	
    	this.selectors= {
    		wrapper: '[data-role=nav]',
    		scroller: '[data-role="nav"] div',
    		thumbnails: '[data-role=nav] div ul li',
    		images: '[data-role=nav] div ul li img',
    		prev: '.nav-prev',
    		next: '.nav-next'
    	}
    	
    	this.width= {
			item: 0,
			page: 0,
			total: 0
    	}
    	
    	this.scroller= null;
    	this.pages= 0;
    	this.keyframes= new Array();
    	
    	this.init();
    }
    
    $.extend(NavSlide.prototype, {
    	
    	init: function(){
    		this.element.addClass(this.touchbehavior?'touch':'no-touch');
    		
	    	var thumbnails= $(this.selectors.thumbnails),
	    		images= $(this.selectors.images),
				length= thumbnails.length,
				items= this.options.items, 
				width= Math.round($(window).width() / items),
				total= length*width; 
	    	
	    	this.width.item= width;
	    	this.width.page= this.options.items * this.width.item;
	    	this.width.total= total;
	    	this.pages= Math.floor(length/items);
			
	    	thumbnails.width(this.width.item);
	    	images.width(this.width.item);
			$(this.selectors.scroller).width(this.width.total);
			
			var options= $.extend(true, {}, ( this.touchbehavior ? this.options.scroll_touch : this.options.scroll_no_touch ) );
			this.scroller= $(this.selectors.wrapper).niceScroll(this.selectors.scroller, options);
			
			setTimeout($.proxy(function(){
				var x=0, page=1;
				
		    	while( x <= this.scroller.page.maxw){
		    		var x1= x,
		    			x2= x+this.width.page-1;
		    		
		    		if(x2>this.scroller.page.maxw)
		    			x2= this.scroller.page.maxw;
		    		
		    		if(x1<x2)
		    			this.keyframes.push({page: page, x1: x1, x2: x2});
		    		
		    		x= x+this.width.page;		    		
		    		page++;
		    	}
		    	
		    	this.init_buttons();
			}, this), 200);	    				
			
			this.scroller.scrollend($.proxy(this.on_scroll_end, this));
    	},
    	
    	init_triggers: function(){    		
        	$(this.selectors.prev).click($.proxy(function(e){ e.preventDefault(); this.prev_page(); }, this));        	
        	$(this.selectors.next).click($.proxy(function(e){ e.preventDefault(); this.next_page(); }, this));
    	},
    	
    	init_buttons: function(){
    		if(!this.touchbehavior){
	    		var current= this.getCurrentPage(true),
	    			x= this.scroller.getScrollLeft();
	    		
	    		//Left button
	    		if(current.page==1 && x<=0){
	    			$(this.selectors.prev).fadeOut(180);
	    		}else{
	    			$(this.selectors.prev).fadeIn(300);
	    		}
	    		
	    		//Right button
	    		if(current.page==this.pages && x>=current.x2){
	    			$(this.selectors.next).fadeOut(180);
	    		}else{
	    			$(this.selectors.next).fadeIn(300);
	    		}    		
    		}
    	},
    	
    	on_scroll_end: function(){
    		this.init_buttons();
    	},
    	
    	getCurrentPage: function(more_info){
    		if(typeof more_info != "boolean")
    			more_info= false;
    		
    		var x= this.scroller.getScrollLeft(),
    			page= undefined;
    		
    		$.each(this.keyframes, $.proxy(function(index, item){
    			if(x>=item.x1 && x<=item.x2)
    				page= ( more_info ? item : item.page );    			
    		}, this));
    		
    		return page;
    	},
    	
    	scrollToPage: function(page){
    		var x;
    		
    		if( page <= 1 )
    			x= 0;
    		else if( page > this.pages )
    			x= this.keyframes[ (this.keyframes.length-1) ].x2;
    		else{
				x= this.keyframes[ (page-1) ].x1;
    		}
    		
    		this.scroller.doScrollLeft(x);
    	},
    	
    	next_page: function(){
    		this.scrollToPage(this.getCurrentPage()+1);
    	},
    	
    	prev_page: function(){
    		var current= this.getCurrentPage(true);
    		var page= (this.scroller.getScrollLeft() > current.x1 ? current.page : current.page-1 );
    		this.scrollToPage(page);
    	}
    	    	
    });
    
    $.fn.navSlide = function (options) {
	    if (!$(this).data('navslide')) {
	        $(this).data('navslide', new NavSlide(this, options));
	    }
	    return $(this).data('navslide');
    }    
    

    /***************************************
	 *				BgSlide
	 *	Events >> eventName [data]:
	 *		- bgSlideImageLoad [slide]
	 *		- bgSlideLoad [slides]
	 ***************************************/
    function BgSlide(element, options) {
        this.element = $(element);      
               
        this.imgs = {
    		active: 'img.active',
    		ready: 'img[ready]',
        	desktop: 'img[src-desktop]',
        	tablet: 'img[src-tablet]',
        	smartphone: 'img[src-smartphone]'
        }

        this.options = $.extend(true, {
        	device: 'smartphone',
        	view: 'landscape',
			width: $(window).width(),
			height: $(window).height(),
        	time: {
        		transition: 1500,
        		view: 10000
        	}
        }, options);
        
        this.device= this.options.device;
        this.timer= null;
        
        this.css= $('body').css('background');
        
        this.init();
    }

    $.extend(BgSlide.prototype, {
    	
        init: function () {   		
    		this.element.one('bgSlideImageReady', $.proxy(function(){
    			this.start();
    		},this));    	
    		
    		this.preload();
	    },
	    
	    preload: function(){
	    	var that= this,
	    		images= this.element.find( this.imgs[this.device] );
	    	
	    	$.each(images, $.proxy(function(index, image){
	    		$(image).load(function(){ 
	    			$(this).attr('ready', 'true'); 
	    			that.element.trigger('bgSlideImageReady'); 
    			});
	    		$(image).attr('src', $(image).attr('src-'+this.device));
	    	},this));	    	
	    },
	    
	    start: function(){
	    	this.background();
	    	this.timer= setInterval($.proxy(this.next, this), this.options.time.view);
	    	this.next();
	    },
	    
	    stop: function(){
	    	clearInterval(this.timer);
	    	this.timer= null;
	    },
	    
	    next: function(){
	    	var images= this.element.find( this.imgs[this.device] ),
	    		ready= images.filter( this.imgs.ready ),
	    		active= ready.filter( this.imgs.active ),
	    		next= $(ready[ready.index(active)+1]);
	    	
	    	if(next.length == 0)
	    		next= ready.first();
	    	
	    	if( ready.index(active) != ready.index(next) ){
		    	active.fadeOut(this.options.time.transition, function(){ $(this).removeClass('active'); });
		    	next.fadeIn(this.options.time.transition, function(){ $(this).addClass('active'); });
		    	next.cover();		    	
	    	}
	    },
	    
	    background: function(){
	    	this.element.find('img').css('opacity', '0.5');
	    },
	    
	    foreground: function(){
	    	this.element.find('img').css('opacity', '1');
	    }
        
    });

    $.fn.bgSlide = function (options) {
	    if (!$(this).data('bgslide')) {
	        $(this).data('bgslide', new BgSlide(this, options));
	    }
	    return $(this).data('BgSlide');
    }

})(window, document, jQuery);


$(document).ready(function(){
	$('body').site();
});


